/*
 * RecStoreHandler.java
 *
 * Copyright (C) 2007 Irving Bunton
 * http://code.google.com/p/jlogmicro/source
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
// Expand to define CLDC define
//#define DCLDCV10
// Expand to define test define
//#define DNOTEST
// Expand to define logging define
//#define DLOGGING
//#ifdef DLOGGING
package net.sf.jlogmicro.util.logging;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Vector;
import java.util.Hashtable;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;

import net.sf.jlogmicro.util.logging.Handler;
import net.sf.jlogmicro.util.logging.LogRecord;

public class RecStoreHandler extends BufferedHandler {

	//#ifdef DTEST
//@	public static final boolean debug = true; // UNDO
	//#endif
	public static final String REC_STORE_NAME = "JLOG_REC_STORE_NAME";
	private Vector vrecStore = new Vector();

	public RecStoreHandler() {
	}

	public void publish(LogRecord record) {
		synchronized (this) {
			try {
				if (view == null) {
					openView(true);
					if (view == null) {
						return;
					}
				}
				RecordStore recStore = (RecordStore)view;
				String msg;
				try {
					msg = formatter.format(record);
				} catch (OutOfMemoryError e) {
					record.setMessage("Out of memory.  Cannot log message.");
					msg = formatter.format(record);
				}
				byte[] bout = null;
				try {
					bout = msg.getBytes("UTF-8");
				} catch (UnsupportedEncodingException uee) {
					bout = msg.getBytes();
				}
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				DataOutputStream dos = new DataOutputStream(bos);
				dos.writeLong(record.getMillis());
				dos.write(bout, 0, bout.length);
				recStore.addRecord(bos.toByteArray(), 0, bos.size());
				/* FIX Use header rec with start # and # consecutive or range
				if ((maxEntries != 0) && (vrecStore.size() >= maxEntries)) {
					recStore.setRecord(((Integer)vrecStore.elementAt(maxEntries -
									1)).intValue(),
										 bos.toByteArray(), 0, bos.size());
				} else {
					vrecStore.addElement(new Integer(
								recStore.addRecord(bos.toByteArray(), 0,
									bos.size())));
				} */
			} catch (Throwable e) {
				System.out.println("publish " + e.getClass().getName() + " " 
						+ e.getMessage());
				e.printStackTrace();
			}
		}
	}

	public synchronized Object openView(boolean append) {

		//#ifdef DTEST
//@		if (debug) { System.out.println("openView append=" + append); }
		//#endif
		try {
			if (name == null) {
				name = REC_STORE_NAME;
			}
			if (view == null) {
				view = RecordStore.openRecordStore(name, true);
			}

			RecordStore recStore = (RecordStore)view;
			final int rnum = recStore.getNumRecords();
			if (!append || (rnum > maxEntries)) {
				removeView(rnum - maxEntries);
			}
			RecordEnumeration erec = recStore.enumerateRecords(null, null,
					false);
			if ((erec == null) || !erec.hasNextElement()) {
				return view;
			}
			int ic = 0;
			for (;(ic < maxEntries) && erec.hasNextElement(); ic++) {
				int id = erec.nextRecordId();
				vrecStore.addElement(new Integer(id));
			}

        } catch (Throwable e) {
            System.out.println("openView openRecStore " + e.getClass().getName() + " " 
					+ e.getMessage());
			e.printStackTrace();
		}
		//#ifdef DTEST
//@		if (debug) { System.out.println("openView append=" + append); }
		//#endif
		return view;
	}

	public void removeView() {
		//#ifdef DTEST
//@		if (debug) { System.out.println("removeView"); }
		//#endif
		try {
			if (view == null) {
				openView(false);
			}
			RecordStore recStore = (RecordStore)view;
			removeView(maxEntries - recStore.getNumRecords());
			closeView();
        } catch (Throwable e) {
            System.out.println("removeView openRecStore " + e.getClass().getName() + " " 
					+ e.getMessage());
			e.printStackTrace();
		}
	}

	private void removeView(int nbr) {
		//#ifdef DTEST
//@		if (debug) { System.out.println("removeView nbr=" + nbr); }
		//#endif
		try {
			RecordStore recStore = (RecordStore)view;
			RecordEnumeration erec = recStore.enumerateRecords(null, null,
					false);
			if ((erec == null) || !erec.hasNextElement()) {
				return;
			}
			for (int ic = 0; (ic < nbr) && erec.hasNextElement(); ic++) {
				int id = erec.nextRecordId();
				recStore.deleteRecord(id);
			}
		} catch (Throwable e) {
			System.out.println("removeView " + e.getClass().getName() + " " 
					+ e.getMessage());
			e.printStackTrace();
		}
	}

    public void closeView() {
		if (view != null) {
			try {
				((RecordStore)view).closeRecordStore();
			} catch( Exception e ){
				e.printStackTrace();
			} finally {
				view = null;
			}
		}
	}

}
//#endif
